package com.psbc.data.trans.common.utils;

import cn.hutool.json.JSONObject;
import com.psbc.data.trans.common.XmlLabel;
import com.psbc.data.trans.common.exception.BusinessException;
import com.psbc.data.trans.datasource.pg.entity.Columns;
import com.psbc.data.trans.vo.XmlDataHeadVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * xml文件数据处理
 */
@Slf4j
public class XmlDataUtil {

    /**
     * 设置XML文件头部数据。
     * 该方法用于根据提供的XML文件路径和XML数据头部信息对象，更新XML文件中的DATAHEAD元素的各个子元素值。
     *
     * @param xmlFilePath XML文件的路径。
     * @param dataHeadVO 包含XML数据头部信息的对象，各字段对应DATAHEAD元素的子元素。
     *
     * @throws BusinessException 如果更新XML文件过程中出现错误，则抛出业务异常。
     */
    public static void setXmlDataHead(String xmlFilePath, XmlDataHeadVO dataHeadVO){

        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();

            // 加载XML文件
            Document doc = dBuilder.parse(xmlFilePath);

            // 获取DATAHEAD元素
            Element dataHeadElement = (Element) doc.getElementsByTagName("DATAHEAD").item(0);

            // 填充各个子元素的值
            setXmlElementValue(dataHeadElement, "DATA_NAME", dataHeadVO.getDataName());
            setXmlElementValue(dataHeadElement, "PRIMARY_KEY", dataHeadVO.getPrimaryKey());
            if (!StringUtils.isEmpty(dataHeadVO.getUpdateFlag())) {
                setXmlElementValue(dataHeadElement, "UPDATE_FLAG", dataHeadVO.getUpdateFlag());
            }
            if (!StringUtils.isEmpty(dataHeadVO.getDeleteFlag())) {
                setXmlElementValue(dataHeadElement, "DELETE_FLAG", dataHeadVO.getDeleteFlag());
            }
            setXmlElementValue(dataHeadElement, "DATA_TYPE", dataHeadVO.getDataType());
            setXmlElementValue(dataHeadElement, "ROW_NUM", String.valueOf(dataHeadVO.getRowNum()));
            setXmlElementValue(dataHeadElement, "PAGE_NUM", String.valueOf(dataHeadVO.getPageNum()));
            setXmlElementValue(dataHeadElement, "FIELD_NUM", String.valueOf(dataHeadVO.getFieldNum()));

            // 保存修改后的XML文件
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(doc);
            StreamResult result = new StreamResult(new File(xmlFilePath));
            transformer.transform(source, result);

            log.info("XML file {} updated successfully.",xmlFilePath);

        } catch (ParserConfigurationException | IOException | TransformerException | SAXException e) {
            log.error("Error updating XML file DATAHEAD tag: " + e.getMessage());
            throw new BusinessException("XML文件写入失败");
        }

    }

    /**
     * 设置XML元素的值。
     * 如果指定的标签名的元素已存在，则直接设置该元素的文本内容；
     * 如果不存在，则会先创建该标签的元素，然后将其添加到父元素中，并设置其文本内容。
     *
     * @param parentElement 父元素，将在此元素下查找或创建子元素。
     * @param tagName       要查找或创建的子元素的标签名。
     * @param value         要设置的子元素的文本内容。
     */
    private static void setXmlElementValue(Element parentElement, String tagName, String value) {
        // 查找或创建指定标签的元素
        Element element = (Element) parentElement.getElementsByTagName(tagName).item(0);
        if (element == null) {
            element = parentElement.getOwnerDocument().createElement(tagName);
            parentElement.appendChild(element);
        }

        // 设置元素的文本值
        element.setTextContent(value);
    }

    public static void creatFieldXml(String filepath, String creatPath, Set<String> textValue, List<JSONObject> list) {
        try {
            // 创建DocumentBuilderFactory
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            // 通过DocumentBuilderFactory创建DocumentBuilder
            DocumentBuilder builder = factory.newDocumentBuilder();
            // 通过DocumentBuilder解析XML文件
            Document document = builder.parse(filepath);

            // 创建一个新的子节点
            NodeList parentNodeFieldList = document.getElementsByTagName(XmlLabel.FIELDS);
            List<String> keyList = new ArrayList<>();
            int i = 1;
            for (String key : textValue) {
                Element childElement = document.createElement(XmlLabel.FIELD);
                childElement.setAttribute(XmlLabel.FIELD_ID, String.valueOf(i));
                childElement.setAttribute(XmlLabel.FIELD_TYPE, XmlLabel.FIELD_VALUE);
                childElement.setTextContent(key);
                keyList.add(key);
                if (parentNodeFieldList != null && parentNodeFieldList.getLength() > 0) {
                    Node parentNode = parentNodeFieldList.item(0);
                    // 将子节点添加到父节点
                    parentNode.appendChild(childElement);

                }
                i++;
            }
            // 生成数据
            StringBuffer sb = new StringBuffer();
            for (JSONObject obj : list) {
                for (int j = 0; j < keyList.size(); j++) {
                    sb.append(obj.get(keyList.get(j)));
                    if (j < keyList.size()-1) {
                        sb.append(XmlLabel.PAGE_TEXT_FLAG_NOUN);
                    }
                }
                sb.append(XmlLabel.PAGE_TEXT_FLAG_END);
            }
            NodeList parentNodePageList = document.getElementsByTagName(XmlLabel.DATABODY);
            Element childElement = document.createElement(XmlLabel.PAGE);
            childElement.setAttribute(XmlLabel.PAGE_PAGENO_KEY, XmlLabel.PAGE_PAGENO_VALUE);
            childElement.setAttribute(XmlLabel.PAGE_RECORDNUM_KEY, String.valueOf(list.size()));
            childElement.setTextContent(sb.toString());
            if (parentNodePageList != null && parentNodePageList.getLength() > 0) {
                Node parentNode = parentNodePageList.item(0);
                // 将子节点添加到父节点
                parentNode.appendChild(childElement);

            }
            // 创建TransformerFactory
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            // 通过TransformerFactory创建Transformer
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes");
            transformer.setOutputProperty("{", "2");
            // 将修改后的Document对象写回XML文件
            transformer.transform(new DOMSource(document), new StreamResult(creatPath));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    public static void creatFieldXml(String filepath, String creatPath, XmlDataHeadVO<Columns> xmlDataHeadVO) {
        try {
            // 创建DocumentBuilderFactory
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            // 通过DocumentBuilderFactory创建DocumentBuilder
            DocumentBuilder builder = factory.newDocumentBuilder();
            // 通过DocumentBuilder解析XML文件
            Document document = builder.parse(filepath);

            // 创建一个新的子节点
            NodeList parentNodeFieldList = document.getElementsByTagName(XmlLabel.FIELDS);
            for (Columns columns : xmlDataHeadVO.getColumns()) {
                Element childElement = document.createElement(XmlLabel.FIELD);
                childElement.setAttribute(XmlLabel.FIELD_ID, columns.getOrdinalPosition());
                childElement.setAttribute(XmlLabel.FIELD_TYPE, columns.getDataType());
                childElement.setTextContent(columns.getColumnName());
                if (parentNodeFieldList != null && parentNodeFieldList.getLength() > 0) {
                    Node parentNode = parentNodeFieldList.item(0);
                    // 将子节点添加到父节点
                    parentNode.appendChild(childElement);

                }
            }
            NodeList parentNodePageList = document.getElementsByTagName(XmlLabel.DATABODY);
            Element childElement = document.createElement(XmlLabel.PAGE);
            childElement.setAttribute(XmlLabel.PAGE_PAGENO_KEY, XmlLabel.PAGE_PAGENO_VALUE);
            childElement.setAttribute(XmlLabel.PAGE_RECORDNUM_KEY, XmlLabel.PAGE_PAGENO_VALUE);
            childElement.setTextContent(xmlDataHeadVO.getDataBody());
            if (parentNodePageList != null && parentNodePageList.getLength() > 0) {
                Node parentNode = parentNodePageList.item(0);
                // 将子节点添加到父节点
                parentNode.appendChild(childElement);

            }
            // 创建TransformerFactory
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            // 通过TransformerFactory创建Transformer
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes");
            transformer.setOutputProperty("{", "2");
            // 将修改后的Document对象写回XML文件
            transformer.transform(new DOMSource(document), new StreamResult(creatPath));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


}
